﻿using CPPEI.Coolzon.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CPPEI.Coolzon.Designer.Views
{
    /// <summary>
    /// PartTreeView.xaml 的交互逻辑
    /// </summary>
    public partial class PartTreeView : UserControl
    {
        private DesignView _designView;
        /// <summary>
        /// 通过designview的select事件触发之后被选中的项目
        /// </summary>
        private PartTreeViewModel _selectItemByEvent;
        private System.Collections.Hashtable htPartLib = new System.Collections.Hashtable();
        private System.Collections.ObjectModel.ObservableCollection<PartTreeViewModel> partTreeList = new System.Collections.ObjectModel.ObservableCollection<PartTreeViewModel>();
        public PartTreeView()
        {
            InitializeComponent();
            InitPartLibHashtable();
            InitEditMenu();


            this._ctlTreeViewPart.ItemsSource = partTreeList;
        }

        private void InitPartLibHashtable()
        {
            for (int partLibIndex = 0; partLibIndex < Configuration.Client.Config.PartLibs.PartLibs.Count; partLibIndex++)
            {
                Configuration.Client.PartLib partlib = Configuration.Client.Config.PartLibs.PartLibs[partLibIndex];
                string filePath = string.Format("{0}{1}{2}.xml", Configuration.Client.Config.PartLibs.PartLibsBaseAddress, Configuration.Client.Config.PartLibs.PartLibsDirectory, partlib.Name);

                System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
                xDoc.Load(filePath);

                CPPEI.Coolzon.Metadata.PartLib partLib = Metadata.PartLibXmlProxy.Load(filePath);
                foreach (var item in partLib.PartList)
                {
                    htPartLib.Add(item.Type, item);
                }
            }
        }

        public void AttachDesignView(DesignView designView)
        {
            this._designView = designView;
            this._designView.Opened += _designView_Opened;
            this._designView.Closed += _designView_Closed;
            this._designView.Added += _designView_Added;
            this._designView.Removed += _designView_Removed;
            this._designView.SelectedChanged += _designView_SelectedChanged;
        }

        public void DeattachDesignView()
        {
            this._designView.Opened -= _designView_Opened;
            this._designView.Closed -= _designView_Closed;
            this._designView.Added -= _designView_Added;
            this._designView.Removed -= _designView_Removed;
            this._designView.SelectedChanged -= _designView_SelectedChanged;
            this._designView = null;
        }

        void _designView_SelectedChanged(Coolzon.UI.Part partInstance)
        {
            if (partInstance == null)
            {
                // 取消节点的选中状态
                PartTreeViewModel curSelItem = this._ctlTreeViewPart.SelectedItem as PartTreeViewModel;
                if (curSelItem != null)
                {
                    curSelItem.IsSelected = false;
                }
                return;
            }
            PartTreeViewModel selItem = GetTreeViewItemByPart(partInstance, null);

            if (selItem != null)
            {
                _selectItemByEvent = selItem;
                selItem.IsSelected = true;
            }
        }

        private PartTreeViewModel GetTreeViewItemByPart(Coolzon.UI.Part partInstance, PartTreeViewModel selItem)
        {
            // 让对应的节点变成选中状态
            string[] namePathArr = _GetPartPathArr(partInstance);
            for (int index = 0; index < namePathArr.Length; index++)
            {
                string name = namePathArr[index];

                if (selItem != null)
                {
                    selItem = _GetTreeViewItem(selItem, name);
                }
                else
                {
                    PartTreeViewModel root = partTreeList[0] as PartTreeViewModel;
                    if (root != null && string.Equals(root.Name, name))
                    {
                        selItem = root;
                    }
                }

                if (selItem == null)
                {
                    break;
                }
            }

            return selItem;
        }

        void _designView_Opened(Coolzon.UI.ScenePart scene)
        {
            Clear();

            if (scene != null)
            {
                ConvertScene(scene);
            }
        }

        public void Clear()
        {
            partTreeList.Clear();
        }

        private void _designView_Closed(Coolzon.UI.ScenePart scene)
        {
            Clear();
        }

        /// <summary>
        /// 选择了一个节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void onCtlTreeViewPartSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            PartTreeViewModel selNode = this._ctlTreeViewPart.SelectedItem as PartTreeViewModel;
            if (selNode != null)
            {
                if (_selectItemByEvent == selNode)
                {
                    // 这个节点是由选中treeview节点造成的，所以不在通知designview了
                    _selectItemByEvent = null;
                    return;
                }
                CPPEI.Coolzon.UI.Part part = selNode.Tag as CPPEI.Coolzon.UI.Part;
                this._designView.API_Select(part.Name);
            }
        }

        void _designView_Removed(Coolzon.UI.Part part)
        {
            string[] namePathArr = this._GetPartParentPathArr(part);
            PartTreeViewModel parentItem = null;
            for (int index = 0; index < namePathArr.Length; index++)
            {
                string name = namePathArr[index];

                if (parentItem != null)
                {
                    parentItem = _GetTreeViewItem(parentItem, name);
                }
                else
                {
                    PartTreeViewModel root = partTreeList[0] as PartTreeViewModel;
                    if (string.Equals(root.Name, name))
                    {
                        parentItem = root;
                    }
                }

                if (parentItem == null)
                {
                    break;
                }
            }

            if (parentItem != null)
            {
                for (int i = 0; i < parentItem.Children.Count; i++)
                {
                    if (string.Equals((parentItem.Children[i] as PartTreeViewModel).Name, part.Name))
                    {
                        parentItem.Children.Remove(parentItem.Children[i]);
                        break;
                    }
                }
            }
        }

        void _designView_Added(Coolzon.UI.Part part)
        {
            // 添加组件到tree上

            string[] namePathArr = this._GetPartParentPathArr(part);
            PartTreeViewModel parentItem = null;
            for (int index = 0; index < namePathArr.Length; index++)
            {
                string name = namePathArr[index];

                if (parentItem != null)
                {
                    parentItem = _GetTreeViewItem(parentItem, name);
                }
                else
                {
                    PartTreeViewModel root = partTreeList[0] as PartTreeViewModel;
                    if (root.Name == name)
                    {
                        parentItem = root;
                    }
                }

                if (parentItem == null)
                {
                    break;
                }
            }

            if (parentItem != null)
            {
                ConvertPart(parentItem, part);
            }
        }

        public void ConvertScene(Coolzon.UI.ScenePart scene)
        {
            PartTreeViewModel model = new PartTreeViewModel();
            model.Name = scene.Name;
            model.TypeName = string.Format("({0})", "场景");
            model.IsExpanded = true;
            model.IsSelected = true;
            model.Tag = scene;
            model.Parent = null;
            partTreeList.Add(model);

            List<Coolzon.UI.Part> partList = scene.GetPartList();
            for (int index = 0; index < partList.Count; index++)
            {
                ConvertPart(model, partList[index]);
            }
        }

        private void ConvertPart(PartTreeViewModel parent, Coolzon.UI.Part part)
        {
            PartTreeViewModel model = new PartTreeViewModel();
            model.Name = part.Name;
            if (htPartLib.ContainsKey(part.GetType().ToString()))
            {
                model.TypeName = string.Format("({0})", (htPartLib[part.GetType().ToString()] as Metadata.PartLibItem).Caption);
            }
            else
            {
                model.TypeName = string.Format("({0})", "未知控件");
            }
            model.Tag = part;
            model.Parent = parent;
            model.IconSource = GetIconSourceByType(part.GetType());
            parent.Children.Add(model);

            if (part is Coolzon.UI.IPartContainer)
            {
                Coolzon.UI.IPartContainer container = part as Coolzon.UI.IPartContainer;
                List<Coolzon.UI.Part> partList = container.GetPartList();
                for (int index = 0; index < partList.Count; index++)
                {
                    ConvertPart(model, partList[index]);
                }
                model.IsExpanded = true;
            }
        }
        private string GetIconSourceByType(Type type)
        {
            XPartIconAttribute attribute = (XPartIconAttribute)Attribute.GetCustomAttribute(type, typeof(XPartIconAttribute));
            if (attribute == null)
            {
                return TypeToIconSourceConverter.DEFAULTICONSOURCE;
            }
            else
            {
                return attribute.Source;
            }
        }

        public void BringTreeViewItemTo(string partName, int index)
        {
            PartTreeViewModel selItem = GetTreeViewItemByPartName(partTreeList[0], partName);

            if (selItem != null)
            {
                PartTreeViewModel parent = selItem.Parent as PartTreeViewModel;
                parent.Children.Remove(selItem);
                parent.Children.Insert(index, selItem);
                selItem.IsSelected = true;
            }
        }

        private PartTreeViewModel GetTreeViewItemByPartName(PartTreeViewModel treeItem, string partName)
        {
            if (treeItem != null)
            {
                if (string.Equals(treeItem.Name, partName))
                {
                    return treeItem;
                }
                else
                {
                    if (treeItem.Children.Count > 0)
                    {
                        PartTreeViewModel rightItem = null;
                        foreach (PartTreeViewModel item in treeItem.Children)
                        {
                            rightItem = GetTreeViewItemByPartName(item, partName);
                            if (rightItem != null)
                            {
                                break;
                            }
                        }
                        return rightItem;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 获取组件的父组件名称路径
        /// </summary>
        /// <param name="part"></param>
        /// <returns></returns>
        private string[] _GetPartParentPathArr(CPPEI.Coolzon.UI.Part part)
        {
            List<string> namePathArr = new List<string>();
            CPPEI.Coolzon.UI.Part parentPart = part.ParentPart;

            if (parentPart != null)
            {
                namePathArr.Insert(0, parentPart.Name);
                namePathArr.InsertRange(0, _GetPartParentPathArr(parentPart));
            }

            return namePathArr.ToArray();
        }
        private string[] _GetPartPathArr(CPPEI.Coolzon.UI.Part part)
        {
            List<string> namePathArr = new List<string>();
            namePathArr.Insert(0, part.Name);

            CPPEI.Coolzon.UI.Part parentPart = part.ParentPart;

            if (parentPart != null)
            {
                namePathArr.Insert(0, parentPart.Name);
                namePathArr.InsertRange(0, _GetPartParentPathArr(parentPart));
            }

            return namePathArr.ToArray();
        }

        private PartTreeViewModel _GetTreeViewItem(PartTreeViewModel parentItem, string childName)
        {
            for (int index = 0; index < parentItem.Children.Count; index++)
            {
                PartTreeViewModel childItem = parentItem.Children[index] as PartTreeViewModel;
                if (string.Equals(childItem.Name, childName))
                {
                    return childItem;
                }
            }
            return null;
        }

        private void TreeViewItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            var treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
            if (treeViewItem != null)
            {
                treeViewItem.Focus();
                e.Handled = true;
            }
        }

        static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
        {
            while (source != null && source.GetType() != typeof(T))
                source = VisualTreeHelper.GetParent(source);

            return source;
        }
        
        private void InitEditMenu()
        {
            Type customCommand = typeof(UIPartCommand);
            foreach (var property in customCommand.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
            {
                var command = (ICommand)property.GetValue(null);
                if(command != UIPartCommand.ZoomToNormal && command != UIPartCommand.ZoomToShowAll)
                {
                    MenuItem mi = new MenuItem();
                    mi.Command = command;
                    _ctlEditMI.Items.Add(mi);
                }
            }
            MenuItem miProperty = new MenuItem();
            miProperty.Header = "属性";
            miProperty.Click += MiProperty_Click;
            _ctlEditMI.Items.Add(miProperty);
        }

        private void MiProperty_Click(object sender, RoutedEventArgs e)
        {
            Part selectedPart = UIContext.Current.CurrentDesignView.API_GetSelectedPart();
            AddtitionPropertyWindow window = new AddtitionPropertyWindow(selectedPart, (_ctlTreeViewPart.SelectedItem as PartTreeViewModel).TypeName, UIContext.Current.CurrentDesignView.API_IsEditable());
            window.ShowDialog();
        }

        public void SetVisible(bool isVisible)
        {
            if (!isVisible)
            {
                this._ctlTreeViewPart.ItemsSource = null;
            }
            else
            {
                this._ctlTreeViewPart.ItemsSource = partTreeList;
            }
        }
    }
}
